package com.wjy.common.jwt;

import com.wjy.common.util.PropertiesUtil;
import com.wjy.common.util.RedisUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * @author ybxxszl
 * @desc JwtToken
 * @date 2019/5/4
 */
@Component
public class JwtToken {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PropertiesUtil propertiesUtil;

    public String getToken(String id) {
        String secret = propertiesUtil.getProperty("jwt.secret", String.class, null);
        long time = propertiesUtil.getProperty("jwt.time", long.class, null);

        byte[] keys = DatatypeConverter.parseBase64Binary(secret);
        String jcaName = SignatureAlgorithm.HS256.getJcaName();
        Key key = new SecretKeySpec(keys, jcaName);

        Date exp = new Date(System.currentTimeMillis() + time);

        String token = Jwts.builder().signWith(key).setExpiration(exp).setId(id).compact();

        redisUtil.set("jwt:" + id, token, (int) time / 1000);

        return token;
    }

    public String verifyToken(String token) throws Exception {
        String secret = propertiesUtil.getProperty("jwt.secret", String.class, null);

        byte[] keys = DatatypeConverter.parseBase64Binary(secret);

        String id = Jwts.parser().setSigningKey(keys).parseClaimsJws(token).getBody().get("jti", String.class);

        String t = redisUtil.get("jwt:" + id);

        if (!token.equals(t)) {
            throw new Exception("JWT not in Redis");
        }

        return id;
    }

    public String refreshToken(String token) throws Exception {
        String id = verifyToken(token);

        redisUtil.del("jwt:" + id);

        String t = getToken(id);

        return t;
    }

}
